package template;

import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.DataKeys;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.vfs.VirtualFile;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import template.code.MyDialog;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import java.io.*;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Created by wujf on 2020/6/1.
 */
public class MvpCreatePluginAction extends AnAction {
    Project project;
    VirtualFile selectGroup;
    private String mPackageName;//包名
    private String mClassName;//类名称（处理输入的module name）
    private String mAuthor;//作者
    private String mDescriber;//mocule说明
    private String mLayoutName;//布局名称
    private String mTitle;//页面标题
    private MyDialog myDialog;

    private enum CodeType {
        Activity, Fragment, Contract, Presenter, ListActivity, ListFragment, ListContract, ListPresenter, ListAdapter
    }

    @Override
    public void actionPerformed(AnActionEvent e) {
        project = e.getProject();
        selectGroup = DataKeys.VIRTUAL_FILE.getData(e.getDataContext());
        init();
        project.getBaseDir().refresh(false, true);
    }

    private void init() {
        myDialog = new MyDialog(new MyDialog.DialogCallBack() {
            @Override
            public void ok(String moduleName, String author, String describe, String title, boolean isRecyclerFragment) {
                if (moduleName == null || moduleName.equals("")) {
                    System.out.print("没有输入类名");
                    return;
                }
                //若是module name已经存在，则返回
                String path = selectGroup.getPath() + "/" + moduleName.toLowerCase();
                File file = new File(path);
                if (file.exists()) {
                    Messages.showWarningDialog("module name is exists", "提示 ");
                    return;
                }

                //作者
                if (author == null || author.equals("")) {
                    mAuthor = "wujf";
                } else {
                    mAuthor = author;
                }

                //项目说明
                if (describe == null || describe.equals("")) {
                    mDescriber = "";
                } else {
                    mDescriber = describe;
                }

                //标题
                if (describe == null || title.equals("")) {
                    mTitle = "";
                } else {
                    mTitle = title;
                }
                mLayoutName = "fragment_quick_create_" + humpToUnderline(moduleName);//布局名称quick_create防止重名
                createClassFile(moduleName, isRecyclerFragment);//创建mvp各个类
                project.getBaseDir().refresh(false, true);
                myDialog.dispose();
            }
        });
        myDialog.setVisible(true);
    }


    /**
     * 获取applicationid
     *
     * @return
     */
    private String getApplicationId() {
        String package_name = "";
        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
        try {
            DocumentBuilder db = dbf.newDocumentBuilder();
            Document doc = db.parse(project.getBasePath() + "/App/src/main/AndroidManifest.xml");

            NodeList nodeList = doc.getElementsByTagName("manifest");
            for (int i = 0; i < nodeList.getLength(); i++) {
                Node node = nodeList.item(i);
                Element element = (Element) node;
                package_name = element.getAttribute("package");
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
        return package_name;
    }

    /**
     * 创建MVP架构
     *
     * @param moduleName         输入的名称
     * @param isRecyclerFragment 是否是列表类型页面,默认不是
     */
    private void createClassFile(String moduleName, boolean isRecyclerFragment) {
        if (moduleName.endsWith("Fragment") || moduleName.endsWith("fragment") || moduleName.endsWith("Activity") || moduleName.endsWith("activity")) {
            moduleName = moduleName.substring(0, moduleName.length() - 8);
        }
        String path = selectGroup.getPath() + "/" + moduleName.toLowerCase();
        mPackageName = path.substring(path.indexOf("java") + 5, path.length()).replace("/", ".");
        mClassName = moduleName.substring(0, 1).toUpperCase() + moduleName.substring(1);

        if (!isRecyclerFragment) {
            createClassFile(CodeType.Activity, path);
            createClassFile(CodeType.Contract, path);
            createClassFile(CodeType.Fragment, path);
            createClassFile(CodeType.Presenter, path);
            createLayout();//创建布局文件
        } else {
            createClassFile(CodeType.ListActivity, path);
            createClassFile(CodeType.ListContract, path);
            createClassFile(CodeType.ListFragment, path);
            createClassFile(CodeType.ListPresenter, path);
            createClassFile(CodeType.ListAdapter, path);

        }

    }

    /**
     * 生成mvp框架代码
     *
     * @param codeType
     */
    private void createClassFile(CodeType codeType, String path) {
        String fileName = "";
        String content = "";
        switch (codeType) {
            case Activity:
                fileName = "TemplateActivity.txt";
                content = dealTemplateContent(readFile(fileName));
                writetoFile(content, path, mClassName + "Activity.java");
                break;

            case Fragment:
                fileName = "TemplateFragment.txt";
                content = dealTemplateContent(readFile(fileName));
                writetoFile(content, path, mClassName + "Fragment.java");
                break;

            case Contract:
                fileName = "TemplateContract.txt";
                content = dealTemplateContent(readFile(fileName));
                writetoFile(content, path, mClassName + "Contract.java");
                break;

            case Presenter:
                fileName = "TemplatePresenter.txt";
                content = dealTemplateContent(readFile(fileName));
                writetoFile(content, path, mClassName + "Presenter.java");
                break;

            case ListActivity:
                fileName = "TemplateListActivity.txt";
                content = dealTemplateContent(readFile(fileName));
                writetoFile(content, path, mClassName + "Activity.java");
                break;

            case ListFragment:
                fileName = "TemplateListFragment.txt";
                content = dealTemplateContent(readFile(fileName));
                writetoFile(content, path, mClassName + "Fragment.java");
                break;

            case ListContract:
                fileName = "TemplateListContract.txt";
                content = dealTemplateContent(readFile(fileName));
                writetoFile(content, path, mClassName + "Contract.java");
                break;

            case ListPresenter:
                fileName = "TemplateListPresenter.txt";
                content = dealTemplateContent(readFile(fileName));
                writetoFile(content, path, mClassName + "Presenter.java");
                break;

            case ListAdapter://适配器路劲
                String adapterPath = project.getBasePath() + "/app/src/main/java/" + getApplicationId().replace(".", "/") + "/adapter";//自己项目下的adapter，没有会新建
                fileName = "TemplateAdapter.txt";
                content = dealTemplateContent(readFile(fileName));
                writetoFile(content, adapterPath, mClassName + "Adapter.java");
                break;

        }
    }


    /**
     * 替换模板中字符
     *
     * @param dealContent
     * @return
     */
    private String dealTemplateContent(String dealContent) {
        String content = dealContent.replace("$packagename", mPackageName)
                .replace("$applicationId", getApplicationId())
                .replace("$nameActivity", mClassName + "Activity")
                .replace("$nameFragment", mClassName + "Fragment")
                .replace("$nameContract", mClassName + "Contract")
                .replace("$namePresenter", mClassName + "Presenter")
                .replace("$nameAdapter", mClassName + "Adapter")
                .replace("$layout", mLayoutName)
                .replace("$author", mAuthor)
                .replace("$data", getDate())
                .replace("$description", mDescriber)
                .replace("$title", mTitle);
        return content;
    }

    /**
     * 获取当前时间
     *
     * @return
     */
    public String getDate() {
        Date currentTime = new Date();
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy/MM/dd");
        String dateString = formatter.format(currentTime);
        return dateString;
    }

    /**
     * 创建layout布局文件
     */
    private void createLayout() {
        String layoutPath = project.getBasePath() + "/app/src/main/res/layout/";
        String layout = readFile("layout.txt");
        writetoFile(layout, layoutPath, mLayoutName + ".xml");
    }


    /**
     * 驼峰转下划线
     *
     * @param humpString created by hbd 20160722
     * @return
     */
    public String humpToUnderline(String humpString) {
        if (humpString == null || humpString.equals("")) return "";
        String regexStr = "[A-Z]";
        Matcher matcher = Pattern.compile(regexStr).matcher(humpString);
        StringBuffer sb = new StringBuffer();
        while (matcher.find()) {
            String g = matcher.group();
            matcher.appendReplacement(sb, "_" + g.toLowerCase());
        }
        matcher.appendTail(sb);
        if (sb.charAt(0) == '_') {
            sb.delete(0, 1);
        }
        return sb.toString();
    }


    private String readFile(String filename) {
        InputStream in = null;
        in = this.getClass().getResourceAsStream("code/" + filename);
        String content = "";
        try {
            content = new String(readStream(in));
        } catch (Exception e) {
        }
        return content;
    }

    private void writetoFile(String content, String filepath, String filename) {
        try {
            File floder = new File(filepath);
            // if file doesnt exists, then create it
            if (!floder.exists()) {
                floder.mkdirs();
            }
            File file = new File(filepath + "/" + filename);
            if (!file.exists()) {
                file.createNewFile();
            }

            // 获取该文件的缓冲输出流
            BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file.getAbsoluteFile()), "UTF-8"));
            bw.write(content);
            bw.flush();// 清空缓冲区
            bw.close();

        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private byte[] readStream(InputStream inStream) throws Exception {
        ByteArrayOutputStream outSteam = new ByteArrayOutputStream();
        try {
            byte[] buffer = new byte[1024];
            int len = -1;
            while ((len = inStream.read(buffer)) != -1) {
                outSteam.write(buffer, 0, len);
                System.out.println(new String(buffer));
            }

        } catch (IOException e) {
        } finally {
            outSteam.close();
            inStream.close();
        }
        return outSteam.toByteArray();
    }

}
